<?php

namespace App\Jobs;

use App\Http\Controllers\Live\ActivityController;
use App\Http\Controllers\Live\ShopController;
use App\Models\Live\LiveGroupModel;
use App\Models\ShopHost;
use App\Models\ShopPointsSendLog;
use Exception;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;

class RunRedisListCheckJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    private $data;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($data)
    {
        $this->data=$data;
        $this->onQueue('after_points_points_send_job');
        //
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $flag=$this->data['flag'];
        $cache_key_activity_list=$this->data['cache_key_activity_list'];
        switch($flag){
            //清算派发积分结果，是否有未认领积分进行原账户积分回填否则啥都不做
            case 'clearing_send_points':{
                //积分领取列表ListKey
                if(Redis::EXISTS($cache_key_activity_list)){
                    $activity_list=Redis::LRANGE($cache_key_activity_list,0,9999);//活动列表
                    foreach($activity_list as $v){
                        ////{$shop_id} {$host_id} {$room_id} {$activity_id} {$end_time} {$points} {$amount} {$point}
                        $activity_data=explode(' ',$v);
                        $shop_id=$activity_data[0];
                        $host_id=$activity_data[1];
                        $room_id=$activity_data[2];
                        $activity_id=$activity_data[3];
                        //$cache_key_list=self::REDIS_PREFIX_GROUP_POINTS."{$shop_id}_{$host_id}_{$room_id}_list";
                        if($this->checkActivityIsOffLine($shop_id,$host_id,$room_id)){
                         //如果活动已经下线结束
                         $cache_key_grab_list=ActivityController::REDIS_PREFIX_GROUP_POINTS."{$shop_id}_{$host_id}_{$room_id}_grab_list_".$activity_id;
                         $this->backPoint2Host($cache_key_activity_list,$cache_key_grab_list,$activity_data,$activity_id);
                         $this->publishEmptyGamePointsMsg($room_id);
                        }else{
                         //如果活动还在线进行中但是积分已经抢完
                         if(!$this->checkGamePointsUsedState($shop_id,$host_id,$room_id)){
                            $check_key_list=[
                                    ActivityController::REDIS_PREFIX_GROUP_POINTS."{$shop_id}_{$host_id}_{$room_id}_list_begin_time",//立即发送情况下需等待积分被全部抢完才结束生命周期
                                    ActivityController::REDIS_PREFIX_GROUP_POINTS."{$shop_id}_{$host_id}_{$room_id}_list_end_time",//立即发送情况下需等待积分被全部抢完才结束生命周期
                                    ActivityController::REDIS_PREFIX_GROUP_POINTS."{$shop_id}_{$host_id}_{$room_id}_list_total",//立即发送情况下需等待积分被全部抢完才结束生命周期
                                    ActivityController::REDIS_PREFIX_GROUP_POINTS."{$shop_id}_{$host_id}_{$room_id}_list_average",//立即发送情况下需等待积分被全部抢完才结束生命周期
                                    ActivityController::REDIS_PREFIX_GROUP_POINTS."{$shop_id}_{$host_id}_{$room_id}_list_activity_current",//立即发送情况下需等待积分被全部抢完才结束生命周期
                                    ActivityController::REDIS_PREFIX_GROUP_POINTS."{$shop_id}_{$host_id}_{$room_id}_list"//立即发送情况下需等待积分被全部抢完才结束生命周期
                            ];
                            //这种情况是立即发送积分，立即发送情况下活动生命周期是等待所有积分被抢完才结束活动，这种情况就需要对活动生命周期进行手动的结束
                            foreach($check_key_list as $v_1){
                                Redis::DEL($v_1);
                            }
                            $this->publishEmptyGamePointsMsg($room_id);
                         }else{
                            //如果活动还在线进行中但是积分没有抢完
                         }
                       }
                    }
                }
                break;
            }
        }
    }
    private function checkActivityIsOffLine($shop_id,$host_id,$room_id){
        $key=ActivityController::REDIS_PREFIX_GROUP_POINTS."{$shop_id}_{$host_id}_{$room_id}_list_begin_time";
        return Redis::EXISTS($key)?false:true;
    }
    private function checkGamePointsUsedState($shop_id,$host_id,$room_id){
        $key=ActivityController::REDIS_PREFIX_GROUP_POINTS."{$shop_id}_{$host_id}_{$room_id}_list";
        return Redis::EXISTS($key)&&!empty(Redis::LLEN($key))?true:false;
    }
    private function checkActivityActualSendPoints($activity_id){
        $sender=ShopPointsSendLog::find($activity_id);
        if(!empty($sender)){
            if($sender->status=='ACTIVE'){
                return $sender;
            }
        }
        return false;
    }
    private function publishEmptyGamePointsMsg($room_id){
        $rooms=ShopController::getLiveRooms();
        $attr='room_'.$room_id;
        $attr='room_'.$room_id;
        if(isset($rooms->$attr)){
            $room_group_id=$rooms->$attr->group_id;
                            if(!env('API_TEST'))
                            LiveGroupModel::sendGroupMsg($room_group_id,[
                                'code' => 0,
                                'type' => 'no_points',
                                'data'=>null]);
                                else{
                                    Log::debug("测试不群发\r\n");
                                }
        }
    }
    private function backPoint2Host($cache_key_activity_list,$cache_key_grab_list,$activity_data,$activity_id){
                    //如果没有抢购 则需要全额退还 但是没人抢购不会产生 _grab_list
                    $shop_id=$activity_data[0];
                    $host_id=$activity_data[1];
                    $room_id=$activity_data[2];
                    $activity_id=$activity_data[3];
                    $end_time=$activity_data[4];
                    $points=$activity_data[5];
                    $amount=$activity_data[6];
                    $point=$activity_data[7];
                    $activity_current_idName="{$shop_id} {$host_id} {$room_id} {$activity_id} {$end_time} {$points} {$amount} {$point}";
                    if(Redis::EXISTS($cache_key_grab_list)){
                      $grab_size=Redis::SCARD($cache_key_grab_list);
                      $less_size=$amount-$grab_size;
                      $points=bcmul($point,$less_size,2);
                     }else{
                        //没有人抢情况下，积分全退
                     }
                     $data=[
                        'job_runner'=>true,
                        "shop_id"=>$shop_id,
                        "host_id"=>$host_id,
                        "change"=>[
                            "name"=>"退回",
                            "value"=>$points,
                            "msg"=>""
                        ]
                     ];
                     $sender=$this->checkActivityActualSendPoints($activity_id);
                     if(!empty($sender)){//进行积分是否真是发送积分派发操作检测，如果派发时候遇到异常没有派发出 则不需要退回
                        Log::debug('changepoints.url='.route("api.shop.changepoints"));
                        $response=Http::withOptions([
    'verify' => env("cacert_path",'/opt/api/cacert.pem')
])->post(route("api.shop.changepoints"),$data);//服务器CURL SSL cafile配置异常 这里强制写入verify的文件再服务器的地址
                        $ret=$response->json();
                        if(isset($ret['id'])&&!empty($ret['id'])){
                         Log::debug('clearing_send_points.OK.setPoints: '.json_encode($ret));
                         $sender->status='CLOSE';
                         $v=$sender->save();
                         Log::debug('clearing_send_points.OK.退回积分: '.$points.":(sender.status.update={$v})");
                        }else{
                         Log::debug('api.shop.changepoints.fail: '.json_encode($ret));
                        }
                     }else{
                        Log::debug('backPoint2Host: 活动：['.$activity_id.'] 无积分退回');
                     }
                     Redis::DEL($cache_key_grab_list);//删除当前操作积分退回的积分活动的获得积分列表
                     Redis::LREM($cache_key_activity_list,0,$activity_current_idName);//从活动列表移除当前操作积分退回的积分活动
    }
}
